package chapter2.src.com.kkb.array;


import org.junit.jupiter.api.Test;

import java.io.PrintStream;
import java.lang.reflect.Field;
import java.util.*;


class TestArrayList {


    public static ArrayList<Integer> getIntegerArrayList() {


        ArrayList<Integer> integers = new ArrayList<>();

        integers.add(1);
        integers.add(2);
        integers.add(3);
        integers.add(4);
        integers.add(5);
        integers.add(6);
        integers.add(7);
        integers.add(8);
        integers.add(9);
        integers.add(10);
        return integers;


    }


    public static ArrayList<String> getStringList() {

        ArrayList<String> list = new ArrayList<>();
        list.add("林帅");
        list.add("林总");
        list.add("林育容");
        list.add("罗帅");
        list.add("罗总");
        list.add("雷神爷");
        return list;
    }


    public static ArrayList<Person> getPersonList() {


        ArrayList<Person> list = new ArrayList<>();
        list.add(new Person("林育容", 41));
        list.add(new Person("罗帅", 41));
        list.add(new Person("小楼", 31));
        list.add(new Person("杜光亭", 41));

        return list;


    }


    @Test
    public void testConstructor() {


        ArrayList<Integer> integers = new ArrayList<>();
        integers.add(1);
        integers.add(2);
        integers.add(3);
        ArrayList<Integer> integers2 = new ArrayList<>(integers);
        System.out.println(integers2.toString());
        ArrayList<Integer> integers1 = new ArrayList<>(11);
        ArrayList<Integer> integersError = new ArrayList<>(-1);


    }


    @Test
    public void testAdd() throws NoSuchFieldException {


        ArrayList<Integer> integers = new ArrayList<>();

        integers.add(1);
        integers.add(2);
        integers.add(3);
        integers.add(4);
        integers.add(5);
        integers.add(6);
        integers.add(7);
        integers.add(8);
        integers.add(9);
        integers.add(10);
        System.out.println(integers.size());

        Field elementData = integers.getClass().getDeclaredField("elementData");
        System.out.println(elementData);


        integers.add(11);
        System.out.println(integers.size());

    }


    /**
     * 结果:
     * [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
     * [1, 3, 4, 5, 6, 7, 8, 9, 10]
     */
    public static void testRemoveFromIndex() {

        ArrayList<Integer> arrayList = getIntegerArrayList();
        System.out.println(arrayList.toString());
        int index = 1;
        arrayList.remove(index);
        System.out.println(arrayList.toString());
        // arrayList.remove(100);


    }


    /**
     *
     * 如果是 结构简单的 类型还好, 如果是复杂类型的 对象, 例如说 商户model , 订单 model , 很难判断 , 必须重写equals 方法
     * 当他判断某个元素将要被删掉的时候, 调用的是 fastRemove 方法;
     *
     */
    public static void testRemoveFormObj() {
        ArrayList<Integer> arrayList = getIntegerArrayList();
        Integer integer = new Integer(3); //只要传进来的是 包装类 它就认为是 参数是 obj, 而不是 索引值
        System.out.println(arrayList.toString());
        arrayList.remove(integer);
        System.out.println(arrayList.toString());

        ArrayList<Person> personList = getPersonList();
        Person lin = new Person("杜光亭", 41) ;
        System.out.println(personList.toString());
        personList.remove(lin);  //如果你没有重写 equals 方法, 是删不掉的;
        System.out.println(personList.toString());

    }

    /**
     *
     * 很简单的方法, 根据 索引 去把数组对应的值 替换掉就完事了
     *
     * */
    public  static void testSet ( ){

        ArrayList<String> list = getStringList();
        System.out.println(list.toString());
        String s = list.set(3, "罗荣桓元帅");
        System.out.println(list.toString());


    }


    public  static void testGetFromIndex ( ){

        ArrayList<String> stringList = getStringList();
        String s = stringList.get(2); //根据数组下标拿出来
        System.out.println(s);


    }


    public  static void testGetIndexFromObj ( ){

        ArrayList<String> stringList = getStringList();
        String lin = new String("林总");
        int i = stringList.indexOf(lin);
        System.out.println(i);  //找不到 return -1 \ 找到了 return index
    }

    /**
     * 底层调用 int indexOfRange(Object o, int start, int end) {} 方法
     * 用的也是 for 循环判断;
     * */
    public static void testContain(){

        ArrayList<String> stringList = getStringList();
        boolean b = stringList.contains("林总");
        System.out.println(b);


    }



    public void testFor() {
        ArrayList list = new ArrayList();
        list.add("a");
        list.add("b");
        list.add("c");
        for (int i = 0; i < list.size(); i++) {
            System.out.print(list.get(i) + " ");
        }
    }

    /**
     *  ArrayList 继承了 Iterator 接口
     *
     *
     * */
    public static void testIterator() {
        ArrayList<String> list = new ArrayList<>();
        list.add("a");
        list.add("b");
        list.add("c");
        Iterator<String> it = list.iterator();
        while (it.hasNext()) {
            String str = it.next();
            System.out.print(str + " ");
        }

    }





    public static  void testIterator2() {
        ArrayList<String> list = new ArrayList<>();
        list.add("a");
        list.add("b");
        list.add("c");
        Iterator<String> it = list.iterator();
        while (it.hasNext()) {
            String str = it.next();
            System.out.print(str + " ");

            list.remove(str);
//		     list.add(str);
//		     list.set(0, str);
//		      it.remove();
        }
    }


    /**
     * 竟然没有报错;
     * 这个是因为 某种机制 凑巧 逃过了校验而已;
     * */
    public static  void testIterator3() {
        ArrayList<String> list = new ArrayList<>();
        list.add("a");
        list.add("b");
        list.add("c");
        Iterator<String> it = list.iterator();
        while (it.hasNext()) {
            System.out.println(it.next());
            if (it.next().equals("b")){
                list.remove("b");
            }
        }
    }



    @Test
    void testForEach() {
        ArrayList<String> list = new ArrayList<>();
        list.add("a");
        list.add("b");
        list.add("c");
        //使用了增强for , 但是编译到底层还是 使用iterator
        for (String str : list) {
            System.out.print(str + " ");
        }
    }

    @Test
    void testForEach2() {
        ArrayList<String> list = new ArrayList<>();
        list.add("a");
        list.add("b");
        list.add("c");
        String str;
        for (Iterator iterator1 = list.iterator(); iterator1.hasNext(); System.out.print((new StringBuilder(String.valueOf(str))).append(" ").toString()))
            str = (String) iterator1.next();

    }

    @Test
    void testListIterator() {
        ArrayList<String> list = new ArrayList<>();
        list.add("a");
        list.add("b");
        list.add("c");
        ListIterator<String> listIt = list.listIterator();

        while (listIt.hasNext()) {
            System.out.print(listIt.next() + " ");//a b c
        }
        System.out.println("==============");

        while (listIt.hasPrevious()) {

            System.out.print(listIt.previous() + " "); //c b a
        }

    }

    @Test
    void testListIterator2() {
        ArrayList<String> list = new ArrayList<>();
        list.add("a");
        list.add("b");
        list.add("c");
        ListIterator<String> listIt = list.listIterator();


        while (listIt.hasNext()) {
            System.out.print(listIt.next() + " ");//a b c
            listIt.add("1");
        }

        System.out.println("####");

        while (listIt.hasPrevious()) {
            System.out.print(listIt.previous() + " ");//1 c 1 b 1 a
        }

    }


    public  static  void testSubList() {
        ArrayList<String> list = getStringList();
        List<String> subList = list.subList(0, 4);
        for (String str : subList) {
            System.out.print(str + " ");//a
        }

    }




    public static void main(String[] args) {
        testSubList2();
    }



   public static void testSubList2() {
        ArrayList<String> list = new ArrayList<>();
        list.add("a");
        list.add("b");
        list.add("c");

        List<String> subList = list.subList(0, 1);
        for (String str : subList) {
            System.out.print(str + " ");//a
        }
        subList.add("d");
        System.out.println(subList.size());//2
        System.out.println(list.size());//
    }


}
